<template>
    <div
      v-show="visible"
      :style="{
        left: position.left + 'px',
        top: position.top + 'px',
        display: visible ? 'block' : 'none',
      }"
      class="context-menu">

      <template v-for="item in menuItems" :key="item.name">
        <el-upload
          class="menu-item"
          :before-upload="item.beforeUpload"
          :http-request="item.upload"
          v-if="item.actionType === 2">
          {{ item.name }}
        </el-upload>
        <div
          class="menu-item"
          @click="item.action?.call(item, rightClickItem)" v-else>
          {{ item.name }}
      </div>
      </template>
    </div>
</template>
<script lang="ts" setup>
  import { ref, watch } from "vue";
  import styles from "@/styles/variables.module.scss"
  import { useAsideMenuInfoStore } from "@/store/asideMenuInfo";
  import { useTopBreadcrumbInfoStore } from "@/store/topBreadcrumbInfo";
  import { UploadRawFile} from "@/types/type";
  import { UploadRequestOptions } from "@/types/type";

  const asideMenuInfo = useAsideMenuInfoStore()
  const topBreadcrumbInfo = useTopBreadcrumbInfoStore()


   
  interface Props {
    menuItems: ContextMenuItem[];
  }
  
  export interface ContextMenuItem {
    actionType: number; // 1: 普通按钮，2：上传文件
    name: string;
    icon?: string;
    action?: (rightClickItem: any) => void;
    beforeUpload?: (uploadFile: UploadRawFile) => void
    upload? :(uploadOptions: UploadRequestOptions) => void
  }
   
  const props = defineProps<Props>();
  const visible = ref(false);
  const rightClickItem = ref(null);
  const position = ref({
    top: 0,
    left: 0,
  });
   
  const openMenu = (e: MouseEvent, item: any) => {
    let menuCount = props.menuItems.length;
    let windowHeight = window.innerHeight;
    
    let xOffset = 180
    let asideMenuWidth = asideMenuInfo.menuCollapse ? styles.foldMainAsideMenuWidth: styles.mainAsideMenuWidth
    if (asideMenuWidth.endsWith("px")) {
        xOffset = +(asideMenuWidth.substring(0, asideMenuWidth.length-2))
    } else {
        xOffset = +(asideMenuWidth)
    }
    let yOffset = 100
    let headerHeight = topBreadcrumbInfo.showTopBreadcrumb ? styles.totalHeaderHeight: styles.mainHeaderHeight
    if (asideMenuWidth.endsWith("px")) {
        yOffset = +(headerHeight.substring(0, headerHeight.length-2))
    } else {
        yOffset = +(headerHeight)
    }

    visible.value = true;
    position.value.top = Math.min(e.pageY - yOffset, windowHeight - 40 - menuCount * 32);
    position.value.left = e.pageX - xOffset;
    rightClickItem.value = item;
  };
   
  const closeMenu = () => {
    visible.value = false;
  };
   
  watch(visible, () => {
    if (visible.value) {
      document.body.addEventListener("click", closeMenu);
    } else {
      document.body.removeEventListener("click", closeMenu);
    }
  });
   
  defineExpose({ openMenu, closeMenu });
  </script>
  <style scoped lang="scss">
  .context-menu {
    margin: 0;
    background: #fff;
    z-index: 2;
    position: absolute;
    list-style-type: none;
    padding: 4px;
    border-radius: 4px;
    font-size: 12px;
    font-weight: 400;
    color: #333;
    box-shadow: 2px 2px 2px 2px rgba(0, 0, 0, 0.3);
   
    .menu-item {
      padding: 0 15px;
      height: 32px;
      line-height: 32px;
      color: rgb(29, 33, 41);
      cursor: pointer;
    }
    .menu-item:hover {
      background: var(--el-color-primary-light-9);
      border-radius: 4px;
    }
  }
</style>